
#pragma once

#include <windef.h>

#include "Core\Shader.h"

#define GBUFFER_RT_COUNT 7

struct ID3D10Blob;
struct ID3D11Buffer;
struct ID3D11InputLayout;
struct ID3D11PixelShader;
struct ID3D11VertexShader;

class Material;
class Matrix4x4;
class Vector4;

class GBufferShader : public Shader
{
public:
	GBufferShader();
	~GBufferShader();

	// Management.
	//-----------------------------------------------
	// System memory.
	static BOOL IsLoaded();

	static BOOL Load();
	static VOID Unload();

	// Renderer.
	BOOL IsBinded() CONST;

	BOOL Bind();
	VOID Unbind();

	VOID Enable();

	// Parametrization.
	//-----------------------------------------------
	BOOL SetFrameBuffer(CONST Vector4& position,
					    CONST Matrix4x4& world,
					    CONST Matrix4x4& view,
					    CONST Matrix4x4& projection);
	
	BOOL SetMaterialBuffer(CONST Material& material);

protected:
	GBufferShader(CONST GBufferShader&);
	GBufferShader& operator = (CONST GBufferShader&);

	// Shader constant buffers typedefs.
	//-----------------------------------------------
	typedef struct
	{
		FLOAT position[4];
		FLOAT world[16];
		FLOAT view[16];
		FLOAT projection[16];
	} FrameBuffer;

	typedef struct
	{
		FLOAT opacity;
		FLOAT ambient[3];
		FLOAT shininess;
		FLOAT diffuse[3];
		FLOAT specular[3];
		BYTE  padding[4];
	} MaterialBuffer;

private:
	// Attributes.
	//-----------------------------------------------
	// Common data.
	static ID3D10Blob*	 s_vshader_buffer;
	static ID3D10Blob*	 s_pshader_buffer;

	static BOOL			 s_loaded;

	// Handler.
	ID3D11InputLayout*	 m_layout;
	ID3D11VertexShader*	 m_vshader;
	ID3D11PixelShader*	 m_pshader;

	BOOL			     m_binded;

	// Mapped buffers.
	ID3D11Buffer*		 m_frame_buffer;
	ID3D11Buffer*        m_material_buffer;
};

